// admin/system/dao/sys_role_dao.go
package dao

import (
	"go-admin1/admin/system/model"
	"go-admin1/internal/infrastructure/database"
	"go-admin1/internal/infrastructure/logger"

	"go.uber.org/zap"
	"gorm.io/gorm"
)

// SysRoleDao 角色数据访问接口
type SysRoleDao interface {
	Create(role *model.SysRole) error
	GetByID(id int64) (*model.SysRole, error)
	GetByRoleKey(roleKey string) (*model.SysRole, error)
	Update(role *model.SysRole) error
	Delete(id int64) error
	List(page, pageSize int) ([]*model.SysRole, int64, error)
	ListAll() ([]*model.SysRole, error)
	GetByUserID(userID int64) []*model.SysRole
}

type sysRoleDao struct {
	db *gorm.DB
}

// NewSysRoleDao 创建角色数据访问实例
func NewSysRoleDao() SysRoleDao {
	return &sysRoleDao{
		db: database.GetDB(),
	}
}

func (r *sysRoleDao) Create(role *model.SysRole) error {
	logger.Info("创建角色", zap.Int64("role_id", role.RoleID))
	return r.db.Create(role).Error
}

func (r *sysRoleDao) GetByID(id int64) (*model.SysRole, error) {
	logger.Debug("根据ID获取角色", zap.Int64("role_id", id))
	var role model.SysRole
	err := r.db.Where("role_id = ? AND del_flag = '0'", id).First(&role).Error
	return &role, err
}

func (r *sysRoleDao) GetByRoleKey(roleKey string) (*model.SysRole, error) {
	logger.Debug("根据角色键获取角色", zap.String("role_key", roleKey))
	var role model.SysRole
	err := r.db.Where("role_key = ? AND del_flag = '0'", roleKey).First(&role).Error
	return &role, err
}

func (r *sysRoleDao) Update(role *model.SysRole) error {
	logger.Info("更新角色", zap.Int64("role_id", role.RoleID))
	return r.db.Save(role).Error
}

func (r *sysRoleDao) Delete(id int64) error {
	logger.Info("删除角色", zap.Int64("role_id", id))
	return r.db.Where("role_id = ?", id).Delete(&model.SysRole{}).Error
}

func (r *sysRoleDao) List(page, pageSize int) ([]*model.SysRole, int64, error) {
	logger.Debug("获取角色列表", zap.Int("page", page), zap.Int("page_size", pageSize))
	var roles []*model.SysRole
	var total int64

	offset := (page - 1) * pageSize
	db := r.db.Model(&model.SysRole{}).Where("del_flag = '0'")

	if err := db.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	if err := db.Offset(offset).Limit(pageSize).Find(&roles).Error; err != nil {
		return nil, 0, err
	}

	return roles, total, nil
}

func (r *sysRoleDao) ListAll() ([]*model.SysRole, error) {

	var roles []*model.SysRole
	err := r.db.Where("del_flag = '0'").Find(&roles).Error
	return roles, err
}

func (r *sysRoleDao) GetByUserID(userID int64) []*model.SysRole {
	var roles []*model.SysRole
	// 构建查询：左关联三张表，去重，只查询需要的字段
	result := r.db.Model(&model.SysRole{}).
		Distinct("r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, "+
			"r.menu_check_strictly, r.dept_check_strictly, r.status, r.del_flag, "+
			"r.create_time, r.remark").
		Joins("LEFT JOIN sys_user_role ur ON ur.role_id = r.role_id").
		Joins("LEFT JOIN sys_user u ON u.user_id = ur.user_id").
		Joins("LEFT JOIN sys_dept d ON u.dept_id = d.dept_id").
		Where("r.del_flag = '0' AND ur.user_id = ?", userID).
		Find(&roles) // 结果存入 roles 切片

	if result.Error != nil {
		return nil
	}
	return roles
}
